#pragma once

#include <QtCore/QString>
#include <QtCore/QDebug>
#include <QtCore/QRectF>

#include <crs.h>
#include <layerprovider.h>
#include <mapcanvasmap.h>

namespace EasyGIS {
class MapCanvas;

/**
 * 地图容器中的图层，属于数据的集合并不包含任何显示需要的数据
 */
class MapLayer {
 public:
  MapLayer(const QString &id, CRS *crs, MapCanvas *mapCanvas);
  MapLayer(const MapLayer &other);
  MapLayer(MapLayer &&other) noexcept;
  virtual ~MapLayer();
  MapLayer &operator=(const MapLayer &other);
  MapLayer &operator=(MapLayer &&other) noexcept;

 public:
  /**
   * 获取图层的id
   * @return 图层id字符串
   */
  const QString &id() const { return mId; }

  /**
   * 获取图层的显示z值
   * @return z值
   */
  const int zValue() const { return mZValue; }

  /**
   * 获取图层的坐标系
   * @return 图层的坐标系
   */
  const CRS &crs() const { return *mCrs; }

  /**
   * 获取图层所属的map容器
   * @return 图层所属的map容器
   */
  const MapCanvas &mapCanvas() const { return *mMapCanvas; }

  /**
   * 获取图层的数据提供对象
   * @return 图层的数据提供对象
   */
  const LayerProvider &provider() const { return *mProvider; }

  /**
   * 设置图层的id
   * @param id 图层id
   */
  void setId(const QString &id) { mId = id; }

  /**
   * 设置图层的z值
   * @param zValue 图层z值
   */
  void setZValue(const int zValue) { mZValue = zValue; }

  /**
   * 设置图层的坐标系
   * @param crs 图层坐标系
   */
  void setCrs(CRS *const crs) { mCrs = crs; }

  /**
   * 设置图层的数据提供对象
   * @param provider 图层的数据提供对象
   */
  void setProvider(LayerProvider *const provider) { mProvider = provider; }

  /**
   * 获取图层的pixel:m比例尺
   * @return 图层的分辨率
   */
  virtual double resolution() const = 0;

  /**
   * 获取图层的整个显示边界
   * @return 图层的显示边界
   */
  virtual QRectF extent() const = 0;

  /**
   * 获取图层的当前zoom值
   * @return 图层的当前zoom值
   */
  int zoomValue() const { return mZoomValue; }

  /**
   * 设置图层的当前zoom值
   * @param zoom 图层zoom值
   */
  virtual void setZoomValue(int zoom) { mZoomValue = zoom; }

  /**
   * 设置图层所属的地图容器
   * @param map 图层所属的地图容器
   */
  void setMap(MapCanvasMap *map) { mMapCanvasMap = map; }

  /**
   * 获取图层的显示图元，这是图层最终的显示对象
   * @return 图层的显示图元
   */
  MapCanvasMap *map() const { return mMapCanvasMap; }

  /**
   * 判断图层是否可显示
   * @return 图层是否可显示，true显示，false则不显示
   */
  bool isVisible() const {return mIsVisible;}

  /**
   * 设值图层的可显示属性
   * @param visible true为显示，false则不显示
   */
  void setVisiblity(bool visible) {mIsVisible = visible;}

  /**
   * 刷新图层内容
   * @return 刷新图层内容，true则成功，否则为失败
   */
  virtual void update();

 protected:
  QString mId;
  CRS *mCrs;
  int mZValue;
  int mZoomValue;
  LayerProvider *mProvider;
  MapCanvasMap *mMapCanvasMap;
  const MapCanvas *mMapCanvas;
  bool mIsVisible{false};

 private:
  const static int kDefaultZoomValue{10};
};

}
